package com.we.wfc.common.utils;

import com.google.common.collect.Lists;
import org.springframework.util.StringUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static cn.hutool.core.bean.BeanUtil.isEmpty;

/**
 * @Description: OffsetDateTime时间处理工具类
 * @Author:Liangzy(Feeling)
 * @Date:Create in 2019/12/20 11:45 上午
 */
public class OffsetDateTimeUtils {

    private static final String OFFSET_ID = "+08:00";

    /**
     * 获取当前时间 在ISO-8601日历系统中的UTC /格林威治偏移的日期时间，如2007-12-03T10:15:30+08:00
     *
     * @return
     */
    public static OffsetDateTime getDateTimeNow() {
        return OffsetDateTime.now();
    }

    /**
     * 获取当前日期（不设置时分秒） 在ISO-8601日历系统中的UTC /格林威治偏移的日期时间，如2007-12-03T10:15:30+08:00
     *
     * @return
     */
    public static OffsetDateTime getDateNow() {
        OffsetDateTime now = OffsetDateTime.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();
        return getDateTime(year, month, day);
    }

    /**
     * 获取时间（只设置年月日）
     *
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static OffsetDateTime getDateTime(int year, int month, int day) {
        return getDateTime(year, month, day, 0, 0, 0, 0, ZoneOffset.of(OFFSET_ID));
    }

    /**
     * 获取时间（只设置年月日时分秒）
     *
     * @param year  年
     * @param month 月
     * @param day   日
     * @return
     */
    public static OffsetDateTime getDateTime(int year, int month, int day, int hour, int minute, int second) {
        return getDateTime(year, month, day, hour, minute, second, 0, ZoneOffset.of(OFFSET_ID));
    }

    /**
     * 获取时间
     *
     * @param year         年
     * @param month        月
     * @param day          日
     * @param hour         时
     * @param minute       分
     * @param second       秒
     * @param nanoOfSecond 纳秒
     * @param zoneOffset   时区
     * @return
     */
    public static OffsetDateTime getDateTime(int year, int month, int day, int hour, int minute, int second,
                                             int nanoOfSecond, ZoneOffset zoneOffset) {
        OffsetDateTime dateTime = OffsetDateTime.of(year, month, day, 0, 0, 0, 0, zoneOffset);
        return dateTime;
    }

    /**
     * 根据字符串设置日期(yyyy-MM-dd HH:mm:ss)
     *
     * @param text
     * @param text
     * @return
     */
    public static OffsetDateTime parseByYmdhms(CharSequence text) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return parse(text, formatter);
    }

    /**
     * 根据字符串设置日期(yyyy-MM-dd)
     *
     * @param text
     * @param text
     * @return
     */
    public static OffsetDateTime parseByYmd(CharSequence text) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return parse(text, formatter);
    }

    /**
     * 根据字符串设置日期
     *
     * @param text
     * @param formatter
     * @return
     */
    public static OffsetDateTime parse(CharSequence text, DateTimeFormatter formatter) {
        if (StringUtils.isEmpty(text) || formatter == null) {
            return null;
        }
        LocalDateTime localDateTime = LocalDateTime.parse(text, formatter);
        OffsetDateTime dateTime = OffsetDateTime.of(localDateTime, ZoneOffset.of(OFFSET_ID));
        return dateTime;
    }

    /**
     * 格式化时间（默认格式yyyy-MM-dd HH:mm:ss）
     *
     * @param dateTime
     * @return
     */
    public static String formatDateTimeToYmdhms(OffsetDateTime dateTime) {
        return formatDateTime(dateTime, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 格式化时间（默认格式yyyy-MM-dd）
     *
     * @param dateTime
     * @return
     */
    public static String formatDateTimeToYmd(OffsetDateTime dateTime) {
        return formatDateTime(dateTime, "yyyy-MM-dd");
    }

    /**
     * 格式化时间
     *
     * @param dateTime
     * @param patten
     * @return
     */
    public static String formatDateTime(OffsetDateTime dateTime, String patten) {
        if (dateTime == null) {
            return null;
        }
        if (StringUtils.isEmpty(patten)) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(patten));
    }

    /**
     * 获取一天的最小时间
     *
     * @param offsetDateTime
     * @return
     */
    public static OffsetDateTime getDayMinTime(OffsetDateTime offsetDateTime) {
        if (ConverterUtil.isNotEmpty(offsetDateTime)) {
            return offsetDateTime.withHour(0).withMinute(0).withSecond(0);
        } else {
            return null;
        }
    }

    /**
     * 获取一天的最大时间
     *
     * @param offsetDateTime
     * @return
     */
    public static OffsetDateTime getDayMaxTime(OffsetDateTime offsetDateTime) {
        if (ConverterUtil.isNotEmpty(offsetDateTime)) {
            return offsetDateTime.withHour(23).withMinute(59).withSecond(59);
        } else {
            return null;
        }
    }

    /**
     * 设置指定的月份第几天
     *
     * @param mouth
     * @param day
     * @return
     */
    public static OffsetDateTime getMouthAndDay(String mouth, String day) {
        OffsetDateTime now = OffsetDateTime.now();
        if (mouth != null) {
            now = now.withMonth(ConverterUtil.toInteger(mouth));
        }
        if (day != null) {
            now = now.withDayOfMonth(ConverterUtil.toInteger(day));
        }
        return now.withHour(0).withMinute(0).withSecond(0);
    }

    /**
     * 获取当前的年份
     *
     * @author wangh(wisea)
     * @date 2018年3月8日
     * @version 1.0
     */
    public static int getNowYear() {
        LocalDate today = LocalDate.now();
        int year = today.getYear();
        return year;
    }

    /**
     * 获取某月的最后一天日期
     */
    public static OffsetDateTime getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        OffsetDateTime now = OffsetDateTime.now();
        now = now.withYear(year).withMonth(month).withDayOfMonth(lastDay);

        return now.withHour(0).withMinute(0).withSecond(0);
    }

    /**
     * 获取某月的开始一天日期
     *
     * @param year
     * @param month
     * @return
     */
    public static OffsetDateTime getFirstDayOfMonth(int year, int month) {

        OffsetDateTime now = OffsetDateTime.now();

        now = now.withYear(year);
        now = now.withMonth(month);

        return now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
    }

    /**
     * 获取long时间戳
     */
    public static long getLong() {
        long time = OffsetDateTime.now().getLong(ChronoField.INSTANT_SECONDS);
        return time;
    }

    /**
     * 获取近多少天（包含当天）的年月日列表
     *
     * @return
     */
    public static List<String> getDaysYmd(Integer days) {
        OffsetDateTime now = OffsetDateTime.now();
        OffsetDateTime startDate = now.minusDays(days - 1);
        return getStartAndEndYmd(startDate, now);
    }

    /**
     * 获取开始时间到结束时间年月日列表
     *
     * @return
     */
    public static List<String> getStartAndEndYmd(OffsetDateTime startDate, OffsetDateTime endDate) {
        List<String> ymdList = Lists.newArrayList();
        startDate = getDayMinTime(startDate);
        endDate = getDayMaxTime(endDate);
        do {
            ymdList.add(startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        } while ((startDate = startDate.plusDays(1)).isBefore(endDate));
        return ymdList;
    }

    /**
     * 获取某年的年月列表
     *
     * @return
     */
    public static List<String> getYearEndYm(Integer year) {
        List<String> ymdList = Lists.newArrayList();
        OffsetDateTime now = OffsetDateTime.now();
        now = now.withYear(year).withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        do {
            ymdList.add(now.format(DateTimeFormatter.ofPattern("yyyy-MM")));
        } while ((now = now.plusMonths(1)).isBefore(now.withYear(year).withMonth(12).withDayOfMonth(31)));
        return ymdList;
    }

    /**
     * long型转OffsetDateTime
     *
     * @param timestamp
     * @return
     */
    public static OffsetDateTime longToOffsetDateTime(Long timestamp) {
        if (isEmpty(timestamp)) {
            return null;
        }
        if (ConverterUtil.toString(timestamp).length() <= 10) {
            timestamp = timestamp * 1000;
        }
        Date date = new Date(timestamp);
        return OffsetDateTime.ofInstant(date.toInstant(), ZoneId.of("+08:00"));
    }
}
